package com.tiancheng.onecode.controller.admin.platform;

import com.tiancheng.onecode.enums.OrderStatusEnum;
import com.tiancheng.onecode.enums.RefundStatusEnum;
import com.tiancheng.onecode.exception.Asserts;
import com.tiancheng.onecode.model.dto.PayMerchantDTO;
import com.tiancheng.onecode.model.request.admin.*;
import com.tiancheng.onecode.model.response.PageInfo;
import com.tiancheng.onecode.model.response.Result;
import com.tiancheng.onecode.model.response.admin.*;
import com.tiancheng.onecode.service.IBillService;
import com.tiancheng.onecode.service.IMemberOrderRefundService;
import com.tiancheng.onecode.service.IMemberOrderService;
import com.tiancheng.onecode.utils.AmountUtil;
import com.tiancheng.onecode.utils.DateTimeUtil;
import com.tiancheng.onecode.utils.ExcelUtil;
import com.tiancheng.onecode.utils.MerchantContext;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: kellen
 * @Description:
 * @Date: create in 2024/12/23 17:56
 */
@RestController
@RequestMapping("/admin/platform/order")
public class PlatformOrderAdminController {

    @Resource
    private IMemberOrderService memberOrderService;
    @Resource
    private IMemberOrderRefundService memberOrderRefundService;
    @Resource
    private IBillService billService;


    /**
     * 查询订单列表
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/orderPage", method = RequestMethod.POST)
    @ResponseBody
    public Result<PageInfo<QueryOrderRes>> queryPage(@RequestBody QueryOrderReq params) {
        PageInfo<QueryOrderRes> pageInfo = memberOrderService.queryPlatformPage(params);
        return Result.success(pageInfo);
    }

    /**
     * 订单列表-导出
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/orderExport", method = RequestMethod.POST)
    public void orderExport(@RequestBody QueryOrderReq params, HttpServletRequest request,HttpServletResponse response) throws IOException {
        // 设置最多导出50000条
        params.setCurrentPage(1);
        params.setPageSize(50000);
        PageInfo<QueryOrderRes> pageInfo = memberOrderService.queryPlatformPage(params);
        Asserts.isTrue(pageInfo.getTotal()<=50000,"最多支持导出50000条，请使用搜索条件减少导出数量！");
        if(pageInfo.getTotal()>0){
            final List<QueryOrderExportRes> res = pageInfo.getList().parallelStream().map(o -> {
                final QueryOrderExportRes orderExportRes = new QueryOrderExportRes();
                orderExportRes.setOrderId(o.getOrderId());
                orderExportRes.setFlowId(o.getFlowId());
                orderExportRes.setCreatedDt(DateTimeUtil.formatter(o.getCreatedDt(), DateTimeUtil.bj_pattern));
                if (null != o.getPayAmount()) {
                    orderExportRes.setPayAmount(AmountUtil.getYUAN(o.getPayAmount()).toString());
                }
                orderExportRes.setMerchant(o.getMerchantName() + "(" + o.getMerchantCode() + ")");
                orderExportRes.setOrderStatusName(OrderStatusEnum.getDesc(o.getOrderStatus()));
                return orderExportRes;
            }).collect(Collectors.toList());
            String fileName = "订单列表导出.xlsx";
            Workbook workbook = ExcelUtil.buildWorkbook("订单列表", res);
            ExcelUtil.exportExcel(request, response, workbook, fileName);
        }
    }

    /**
     * 查询退款单列表
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/refundPage", method = RequestMethod.POST)
    @ResponseBody
    public Result<PageInfo<QueryOrderRefundRes>> refundPage(@RequestBody QueryOrderRefundReq params) {
        PageInfo<QueryOrderRefundRes> pageInfo = memberOrderRefundService.queryPlatformPage(params);
        return Result.success(pageInfo);
    }


    /**
     * 退款订单列表-导出
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/refundExport", method = RequestMethod.POST)
    @ResponseBody
    public void refundExport(@RequestBody QueryOrderRefundReq params, HttpServletRequest request,HttpServletResponse response) throws IOException{
        // 设置最多导出50000条
        params.setCurrentPage(1);
        params.setPageSize(50000);
        PageInfo<QueryOrderRefundRes> pageInfo = memberOrderRefundService.queryPlatformPage(params);
        Asserts.isTrue(pageInfo.getTotal()<=50000,"最多支持导出50000条，请使用搜索条件减少导出数量！");
        if(pageInfo.getTotal()>0){
            final List<QueryOrderRefundExportRes> res = pageInfo.getList().parallelStream().map(o -> {
                final QueryOrderRefundExportRes orderExportRes = new QueryOrderRefundExportRes();
                orderExportRes.setOrderId(o.getOrderId());
                orderExportRes.setRefundId(o.getRefundId());
                orderExportRes.setCreatedDt(DateTimeUtil.formatter(o.getCreatedDt(), DateTimeUtil.bj_pattern));
                if (null != o.getRefundAmount()) {
                    orderExportRes.setRefundAmount(AmountUtil.getYUAN(o.getRefundAmount()).toString());
                }
                orderExportRes.setMerchant(o.getMerchantName() + "(" + o.getMerchantCode() + ")");
                orderExportRes.setRefundStatus(RefundStatusEnum.getDesc(o.getRefundStatus()));
                return orderExportRes;
            }).collect(Collectors.toList());
            //EasyExcelUtil.export(response,"退款列表导出","退款列表",res,QueryOrderRefundExportRes.class);
            String fileName = "退款列表导出.xlsx";
            Workbook workbook = ExcelUtil.buildWorkbook("退款列表", res);
            ExcelUtil.exportExcel(request, response, workbook, fileName);
        }
    }

    /**
     * 查询订单详情
     *
     * @param orderId 订单号
     * @return
     */
    @RequestMapping(value = "/orderDetail/{orderId}", method = RequestMethod.GET)
    @ResponseBody
    public Result<QueryOrderDetailRes> queryOrderDetail(@PathVariable("orderId") String orderId) {
        QueryOrderDetailRes refund = memberOrderService.queryOrderDetail(orderId);
        return Result.success(refund);
    }

    /**
     * 查询退款订单详情
     *
     * @param refundId 退款单号
     * @return
     */
    @RequestMapping(value = "/refundDetail/{refundId}", method = RequestMethod.GET)
    @ResponseBody
    public Result<QueryOrderRefundRes> queryRefundDetail(@PathVariable("refundId") String refundId) {
        final QueryOrderRefundRes refund = memberOrderRefundService.queryByRefundId(refundId);
        return Result.success(refund);
    }

    /**
     * 查询退款订单详情
     *
     * @param statisticsMerchantOrderReq 查询参数
     * @return
     */
    @RequestMapping(value = "/statisticsByMerchant", method = RequestMethod.POST)
    @ResponseBody
    public Result<StatisticsMerchantOrderRes> statisticsByMerchant(@RequestBody @Valid StatisticsMerchantOrderReq statisticsMerchantOrderReq) {
        final StatisticsMerchantOrderRes res = new StatisticsMerchantOrderRes();
        final List<StatisticsMerchantOrderPayRes> refunds = memberOrderRefundService.statisticsByMerchant(statisticsMerchantOrderReq);
        dataCompletion(statisticsMerchantOrderReq.getBeginDate().toLocalDate(),statisticsMerchantOrderReq.getEndDate().toLocalDate(),refunds);
        final List<StatisticsMerchantOrderPayRes> pay = memberOrderService.statisticsByMerchant(statisticsMerchantOrderReq);
        dataCompletion(statisticsMerchantOrderReq.getBeginDate().toLocalDate(),statisticsMerchantOrderReq.getEndDate().toLocalDate(),pay);
        res.setPay(pay);
        res.setRefund(refunds);
        return Result.success(res);
    }

    private void dataCompletion(LocalDate beginDate,LocalDate endDate,List<StatisticsMerchantOrderPayRes> result){
        List<LocalDate> dates = DateTimeUtil.getDatesBetween(beginDate, endDate);
        for (LocalDate date : dates) {
            if(CollectionUtils.isEmpty(result) || result.stream().noneMatch(r->r.getOrderDate().compareTo(date)==0)){
                StatisticsMerchantOrderPayRes item = new StatisticsMerchantOrderPayRes();
                item.setOrderAmount(0);
                item.setOrderCount(0);
                item.setOrderDate(date);
                result.add(item);
            }
        }
        if(CollectionUtils.isNotEmpty(result)){
            result.sort(Comparator.comparing(StatisticsMerchantOrderPayRes::getOrderDate));
        }
    }

    /**
     * 个人订单、退款统计
     *
     * @param statisticsUserOrderReq 查询参数
     * @return
     */
    @RequestMapping(value = "/statisticsByUserId", method = RequestMethod.POST)
    @ResponseBody
    public Result<StatisticsUserOrderRes> statisticsByUserId(@RequestBody @Valid StatisticsUserOrderReq statisticsUserOrderReq) {
        final StatisticsUserOrderRes res = new StatisticsUserOrderRes();

        List<StatisticsUserOrderItemRes> refunds = memberOrderRefundService.statisticsByUserId(statisticsUserOrderReq);
        final List<StatisticsUserOrderItemRes> pay = memberOrderService.statisticsByUserId(statisticsUserOrderReq);
        res.setPay(pay);
        res.setRefund(refunds);
        return Result.success(res);
    }

    /**
     * 按天统计
     *
     * @param params 查询参数
     * @return
     */
    @RequestMapping(value = "/statisticsByDay", method = RequestMethod.POST)
    @ResponseBody
    public Result<StatisticsMerchantOrderRes> statisticsByDay(@RequestBody @Valid StatisticsMerchantOrderReq params) {
        final StatisticsMerchantOrderRes res = new StatisticsMerchantOrderRes();
        final PayMerchantDTO merchant = MerchantContext.getMerchant();
        if (null != merchant && null == params.getPlatformMerchantId()) {
            params.setPlatformMerchantId(merchant.getPlatformMerchantId());
        }
        if(null!=params.getBeginDate()){
            params.setBeginDate(LocalDateTime.of(LocalDate.from(params.getBeginDate()),LocalDateTime.MIN.toLocalTime()));
        }
        if(null!=params.getEndDate()){
            params.setEndDate(LocalDateTime.of(LocalDate.from(params.getEndDate()),LocalDateTime.MAX.toLocalTime()));
        }
        final List<StatisticsMerchantOrderPayRes> refunds = memberOrderRefundService.statisticsByDay(params);
        dataCompletion(params.getBeginDate().toLocalDate(),params.getEndDate().toLocalDate(),refunds);
        final List<StatisticsMerchantOrderPayRes> pay = memberOrderService.statisticsByDay(params);
        dataCompletion(params.getBeginDate().toLocalDate(),params.getEndDate().toLocalDate(),pay);
        final List<StatisticsMerchantOrderPayRes> settlements=billService.statisticsByDay(params);
        dataCompletion(params.getBeginDate().toLocalDate(),params.getEndDate().toLocalDate(),settlements);
        res.setPay(pay);
        res.setRefund(refunds);
        res.setSettlements(settlements);
        return Result.success(res);
    }

    /**
     * 查询退款订单详情
     *
     * @param orderReq 退款参数
     * @return
     */
    @RequestMapping(value = "/refund", method = RequestMethod.POST)
    @ResponseBody
    public Result<String> refund(@RequestBody @Valid RefundOrderReq orderReq) {
        String refundId =  memberOrderRefundService.refund(orderReq);
        return Result.success(refundId);
    }


}
